package com.mk.legoscans2.activities;

import java.io.ByteArrayOutputStream;

import com.mk.legoscans2.LegoScans3Application;
import com.mk.legoscans2.R;
import com.mk.legoscans2.Scan;
import com.mk.legoscans2.TouchImageView;
import com.mk.legoscans2.Utils;
import com.mk.legoscans2.actionbar.ActionBarActivity;
import com.mk.legoscans2.tasks.SetIsFavoriteTask;
import com.mk.legoscans2.tasks.ToggleFavoriteTask;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ZoomControls;

public class ViewScanActivity extends ActionBarActivity {

	private Scan _scan;
	private ViewHolder _holder;
	private TouchImageView _touchImageView;
	private boolean _isFirstTime = true;
	private State _state = new State();
	private DownloadImageTask _task;
	private SetIsFavoriteTask _setIsFavoriteTask;
	private ToggleFavoriteTask _toggleFavoriteTask;
	private ProgressDialog _progressDialog;
	
	private Context _context;
	
	private static class ViewHolder{
		public RelativeLayout scanImageArea;
		public ImageView navigateRight;
		public ImageView navigateLeft;
		public ProgressBar progressBar;
		public TextView errorMessage;
		public AlertDialog gotoDialog;
		public ZoomControls zoomControls;
	}
	
	private static class State
	{
		public int page = 1;
		public boolean isSaving = false;
	}
	
	@Override
	protected void onCreate(Bundle arg0) {
		
		if(LegoScans3Application.CurrentScan == null)
			new RuntimeException("Current scan is null, this needs to be set before starting a ViewScanActivity.");
		
		super.onCreate(arg0);
		setContentView(R.layout.view_scan);
		
		_context = this;
		
		loadState(arg0);
		
		_scan = LegoScans3Application.CurrentScan;
		
		uppdateTitle();
		
		_holder = new ViewHolder();
		_holder.scanImageArea = (RelativeLayout)findViewById(R.id.scanImageArea);
		_holder.navigateRight = (ImageView)findViewById(R.id.navigateRight);
		_holder.navigateLeft = (ImageView)findViewById(R.id.navigateLeft);
		_holder.progressBar = (ProgressBar)findViewById(R.id.progressBar);
		_holder.errorMessage = (TextView)findViewById(R.id.errorMessage);
		_holder.zoomControls = (ZoomControls)findViewById(R.id.zoomControls);
		
		_holder.zoomControls.setOnZoomInClickListener(new OnClickListener() {
			public void onClick(View v) {
				if(_touchImageView != null)
					_touchImageView.zoom(1.25f);
			}
		});
		
		_holder.zoomControls.setOnZoomOutClickListener(new OnClickListener() {
			public void onClick(View v) {
				if(_touchImageView != null)
					_touchImageView.zoom(0.75f);
			}
		});
		
		_holder.zoomControls.setVisibility(LegoScans3Application.ApplicationPreferences.getShowZoomButtons() ? View.VISIBLE : View.GONE);
		
		_holder.navigateRight.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				_state.page++;
				_task = new DownloadImageTask();
				_task.execute();
			}
		});
		
		_holder.navigateLeft.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				_state.page--;
				_task = new DownloadImageTask();
				_task.execute();
			}
		});
		
		_touchImageView = new TouchImageView(this);
		_touchImageView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		_holder.scanImageArea.addView(_touchImageView, 0);
		
		_task = new DownloadImageTask();
		_task.execute();
		
		if(_state.isSaving && LegoScans3Application.StoreAllImagesTask != null && LegoScans3Application.StoreAllImagesTask.getStatus().equals(AsyncTask.Status.RUNNING))
		{
			_holder.progressBar.setVisibility(View.GONE);
			
			_progressDialog = new ProgressDialog(_context);
			_progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			_progressDialog.setMessage("Saving...");
			_progressDialog.setCancelable(false);
			_progressDialog.setMax(_scan._pageCount);
			_progressDialog.show();

			LegoScans3Application.StoreAllImagesTask.setProgressDialog(_progressDialog);
		}
		else
			_state.isSaving = false;
	}
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.view_scan, menu);
        
        boolean retVal =  super.onCreateOptionsMenu(menu);
        
        _setIsFavoriteTask = new SetIsFavoriteTask(menu, _scan, getActionBarHelper());
        _setIsFavoriteTask.execute();
        
        return retVal;
    }
	
	@Override
	public boolean onOptionsItemSelected(final MenuItem item) {
		LayoutInflater inflater;
		
		switch(item.getItemId())
		{
			case R.id.menu_favorite:
				_toggleFavoriteTask = new ToggleFavoriteTask(item, getActionBarHelper(), _scan);
				_toggleFavoriteTask.execute();
				
				return true;
			case R.id.menu_save:
				String saveDisclaimer = String.format(getResources().getString(R.string.save_disclaimer), Utils.getLocalStorageFolderName(_scan), _scan._pageCount, Utils.getMb(_scan._size) );
				AlertDialog.Builder saveDialogbuilder = new AlertDialog.Builder(this);
				saveDialogbuilder.setMessage(saveDisclaimer)
					.setTitle(getResources().getString(R.string.viewscan_save_dialog_title))
					.setCancelable(true)
					.setPositiveButton(getResources().getString(R.string.viewscan_save_dialog_positive_button_text), new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							dialog.cancel();
							
							LegoScans3Application.StoreAllImagesTask = new StoreAllImagesTask();
							//LegoScans3Application.StoreAllImagesTask = new StoreAllImagesTask(_scan, _progressDialog);
							LegoScans3Application.StoreAllImagesTask.execute();
						}
					})
					.setNegativeButton(getResources().getString(R.string.viewscan_save_dialog_negative_button_text), new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							dialog.cancel();
						}
					});
				
				saveDialogbuilder.create().show();
				return true;
			case R.id.menu_goto:
				
				inflater = (LayoutInflater) _context.getSystemService(LAYOUT_INFLATER_SERVICE);
				View gotoDialog = inflater.inflate(R.layout.goto_dialog, (ViewGroup) findViewById(R.id.goto_dialog_root));
				
				final TextView gotoDialogPageLabel = (TextView)gotoDialog.findViewById(R.id.goto_dialog_page_label);
				gotoDialogPageLabel.setText(_state.page + "/" + _scan._pageCount );
				
				final SeekBar gotoDialogSeekbar = (SeekBar)gotoDialog.findViewById(R.id.goto_dialog_seekbar);
				gotoDialogSeekbar.setMax(_scan._pageCount - 1);
				gotoDialogSeekbar.setProgress(_state.page - 1);
				gotoDialogSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
					public void onStopTrackingTouch(SeekBar seekBar) {}
					public void onStartTrackingTouch(SeekBar seekBar) {}
					
					public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
						gotoDialogPageLabel.setText(progress + 1 + "/" + _scan._pageCount);
					}
				});

				AlertDialog.Builder gotoDialogBuilder = new AlertDialog.Builder(_context);
				gotoDialogBuilder.setView(gotoDialog);
				
				gotoDialogBuilder.setTitle(getResources().getString(R.string.viewscan_goto_dialog_title))
				.setCancelable(true)
				.setPositiveButton(getResources().getString(R.string.viewscan_goto_dialog_positive_button_text), new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
						int newPage = gotoDialogSeekbar.getProgress() + 1;
						if(_state.page != newPage)
						{
							_state.page = newPage;
							_task = new DownloadImageTask();
							_task.execute();
						}
					}
				})
				.setNegativeButton(getResources().getString(R.string.generic_cancel), new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				});
				
				_holder.gotoDialog = gotoDialogBuilder.create(); 
				_holder.gotoDialog.show();
				return true;
		}
		
		return super.onOptionsItemSelected(item);
	}

	@Override
    protected void onSaveInstanceState(Bundle outState) {
    	super.onSaveInstanceState(outState);
    	outState.putInt("LegoScans.Page", _state.page);
    	outState.putBoolean("LegoScans.IsSaving", _state.isSaving);
    }
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		
		if(_holder != null && _holder.gotoDialog != null)
		{
			_holder.gotoDialog.dismiss();
			_holder.gotoDialog = null;
		}
		
		_touchImageView = null;
		_scan = null;
		_holder = null;
		_state = null;
		
		if(_progressDialog != null) {
			_progressDialog.dismiss();
			_progressDialog = null;
		}
		
		if(_task != null) {
			_task.cancel(true);
			_task = null;
		}
		
		if(_setIsFavoriteTask != null){
			_setIsFavoriteTask.cancel(true);
			_setIsFavoriteTask = null;
		}
		
		if(_toggleFavoriteTask != null){
			_toggleFavoriteTask.cancel(true);
			_toggleFavoriteTask = null;
		}
	}
	
	private void loadState(Bundle b) {
		if(b != null)
		{
			_state.page = b.getInt("LegoScans.Page", 1);
			_state.isSaving = b.getBoolean("LegoScans.IsSaving", false);
		}
	}
	
	private void uppdateTitle()
	{
		if(_scan != null && _scan._name != null){
			setTitle(String.format(getResources().getString(R.string.viewscan_title), _scan._boxNumber, _scan._name, _state.page, _scan._pageCount));			
		}
	}
	
	/* DOWNLOAD IMAGE TASK */
	private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
		protected void onPreExecute() {
			_holder.progressBar.setVisibility(View.VISIBLE);
			_holder.errorMessage.setVisibility(View.GONE);
			_holder.navigateLeft.setEnabled(false);
			_holder.navigateRight.setEnabled(false);
			_touchImageView.setVisibility(View.GONE);
		}
		
		protected Bitmap doInBackground(String... arg0) {
			return LegoScans3Application.ApiRepository.getImage(_scan._scanId, _state.page);
		}
		
		protected void onPostExecute(Bitmap result) {
			_holder.progressBar.setVisibility(View.GONE);
			_holder.navigateLeft.setEnabled(true);
			_holder.navigateRight.setEnabled(true);
			
			_holder.navigateRight.setVisibility(_state.page < _scan._pageCount ? View.VISIBLE : View.GONE);
			_holder.navigateLeft.setVisibility(_state.page > 1 ? View.VISIBLE : View.GONE);
			
			uppdateTitle();
			
			if(result == null)
			{
				_holder.errorMessage.setVisibility(View.VISIBLE);
				_touchImageView.setVisibility(View.GONE);
			}
			else
			{
				_touchImageView.setVisibility(View.VISIBLE);
				_holder.errorMessage.setVisibility(View.GONE);
				
				if(_isFirstTime)
				{
					_isFirstTime = false;
					Display display = getWindowManager().getDefaultDisplay();
					_touchImageView.setImage(result, display.getWidth(), display.getHeight());
				}
				else
					_touchImageView.setImageBitmap(result);	
			}
		}
	}
	
	public class StoreAllImagesTask extends AsyncTask<String, Void, Void> {

		private Scan mScan;
		private ProgressDialog mProgressDialog;
		
		public void setProgressDialog(ProgressDialog d)
		{
			mProgressDialog = d;
		}
		
		@Override
		protected void onPreExecute() {
			_progressDialog = new ProgressDialog(_context);
			_progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			_progressDialog.setMessage(getResources().getString(R.string.viewscan_save_progress_message));
			_progressDialog.setCancelable(false);
			_progressDialog.setMax(_scan._pageCount);
			_progressDialog.show();
			
			_state.isSaving = true;
			
			mScan = _scan;
			mProgressDialog = _progressDialog;
		}
		
		@Override
		protected Void doInBackground(String... arg0) {
			for(Integer i = 1; i <= mScan._pageCount; i++ )
			{
				Bitmap bmp = LegoScans3Application.ApiRepository.getImage(mScan._scanId, i);
				if(bmp != null){
					ByteArrayOutputStream stream = new ByteArrayOutputStream();
					if(bmp.compress(CompressFormat.JPEG, 100, stream))
					{
						LegoScans3Application.SdCardFileService.Store(Utils.getLocalStorageFolderName(mScan), Utils.padLeft(i.toString(), 3, '0') + ".jpg", i == 0, stream.toByteArray());
						if(mProgressDialog != null)
							mProgressDialog.setProgress(i);
					}
					
					bmp.recycle();
				}
			}
			return null;
		}
		
		@Override
		protected void onPostExecute(Void result) {
			if(_state != null)
				_state.isSaving = false;
			if(mProgressDialog != null)
			{
				mProgressDialog.cancel();
				mProgressDialog = null;
			}
		}
	}
}
